{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "data10954\r\n"
     ]
    }
   ],
   "source": [
    "# 查看当前挂载的数据集目录\n",
    "!ls /home/aistudio/data/"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "models\tpretrained\r\n"
     ]
    }
   ],
   "source": [
    "# 查看个人持久化工作区文件\n",
    "!ls /home/aistudio/work/"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# # 解压文件 首次运行需解压，去掉注释\r\n",
    "# !unzip -q data/data10954/cat_12_train.zip"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# # 解压文件 首次运行需解压，去掉注释\r\n",
    "# !wget http://paddle-imagenet-models-name.bj.bcebos.com/ResNet101_pretrained.tar"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# # 首次运行\r\n",
    "# import os \r\n",
    "# pre_path = r'work/pretrained'\r\n",
    "# if not os.path.exists(pre_path):\r\n",
    "#     os.makedirs(pre_path)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# # 解压文件 首次运行需解压，去掉注释\r\n",
    "# !tar -xvf ResNet101_pretrained.tar -C work/pretrained"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "import paddle.fluid as fluid\r\n",
    "import paddle\r\n",
    "from paddle.fluid.param_attr import ParamAttr\r\n",
    "import numpy as np\r\n",
    "from PIL import Image\r\n",
    "import os\r\n",
    "import random\r\n",
    "from multiprocessing import cpu_count\r\n",
    "import matplotlib.pyplot as plt\r\n",
    "import shutil\r\n",
    "import pandas as pd\r\n",
    "import reader"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "label_path = 'data/data10954/train_list.txt' # 训练图片名与标签地址\r\n",
    "train_path = 'train_data.txt' # 训练文件路径\r\n",
    "test_path = 'test_data.txt' # 测试文件路径\r\n",
    "train_data = [] # 训练数据\r\n",
    "test_data = [] # 测试数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "with open(label_path,'r') as f:\r\n",
    "    lines = f.readlines()\r\n",
    "    with open(train_path,'w') as train:\r\n",
    "        for i in range(0,2160,180):\r\n",
    "            for line in lines[i:i+144]:\r\n",
    "                train_data.append(line)\r\n",
    "                train.write(line)\r\n",
    "    with open(test_path,'w') as test:\r\n",
    "        for i in range(0,2160,180):\r\n",
    "            for line in lines[i+144:i+180]:\r\n",
    "                test_data.append(line)\r\n",
    "                test.write(line)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "#####  先进行预训练"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "cat_12_train/tO6cKGH8uPEayzmeZJ51Fdr2Tx3fBYSn.jpg\n",
      "cat_12_train/3yMZzWekKmuoGOF60ICQxldhBEc9Ra15.jpg\n",
      "划分完成\n"
     ]
    }
   ],
   "source": [
    "def data_partition():\n",
    "    ''' 将数据集划分为训练集和测试集'''\n",
    "    with open(train_path, 'w') as f_train:\n",
    "        with open(test_path, 'w') as f_test:\n",
    "            with open(label_path,'r') as f:\n",
    "                lines = f.readlines()\n",
    "                del lines[len(lines)-1]\n",
    "                for i,line in enumerate(lines):\n",
    "                    img_path, label = line.split('\\t')\n",
    "                    # 注意有些文件是单通道，这些是不需要利用，运行时会报错\n",
    "                    try:\n",
    "                        img = Image.open(img_path)\n",
    "                        img = np.array(img).astype(np.float32)\n",
    "                        img = img.transpose((2, 0, 1))\n",
    "                        img = img[(2, 1, 0), :, :]\n",
    "                        img = img.flatten().astype('float32') / 255.0\n",
    "                        if i%5 == 0:\n",
    "                            f_test.write(line)\n",
    "                            test_data.append(line)\n",
    "                        else:\n",
    "                            f_train.write(line)\n",
    "                            train_data.append(line)\n",
    "                    except Exception as err:\n",
    "                        # 打印有问题的图片\n",
    "                        print(img_path)\n",
    "\n",
    "data_partition()\n",
    "print(\"划分完成\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "### 数据增强\r\n",
    "train_data_len  = len(train_data)\r\n",
    "test_data_len = len(test_data)\r\n",
    "# 从训练集选择一些加入测试集中\r\n",
    "test_data_exp=random.sample(range(train_data_len), k=300)\r\n",
    "# a 表示追加\r\n",
    "with open(test_path, 'a') as f_test:\r\n",
    "    for i in test_data_exp:\r\n",
    "        f_test.write(train_data[i])\r\n",
    "# 从训练集加入一些数据加入训练集中 重复\r\n",
    "repetitions = 100 # 重复次数\r\n",
    "train_k = 100 # 从训练集一次选择数据量\r\n",
    "for _ in range(repetitions):\r\n",
    "    train_data_exp=random.sample(range(train_data_len), k=train_k)\r\n",
    "    with open(train_path,'a') as f_train:\r\n",
    "        for i in train_data_exp: \r\n",
    "            f_train.write(train_data[i])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "BATCH_SIZE = 32 # 批处理数据的大小\r\n",
    "train_reader = paddle.batch(\r\n",
    "    reader=paddle.reader.shuffle(reader=reader.custom_image_reader(train_path, mode='train'),buf_size=1280000), \r\n",
    "     batch_size=BATCH_SIZE)\r\n",
    "test_reader = paddle.batch(reader.custom_image_reader(train_path, mode='test'),\r\n",
    "                        batch_size=BATCH_SIZE)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "定义训练网络\n"
     ]
    }
   ],
   "source": [
    "##定义残差网络\n",
    "def resnet(input):\n",
    "    def conv_bn_layer(input, num_filters, filter_size, stride=1, groups=1, act=None, name=None):\n",
    "        conv = fluid.layers.conv2d(input=input,\n",
    "                                   num_filters=num_filters,\n",
    "                                   filter_size=filter_size,\n",
    "                                   stride=stride,\n",
    "                                   padding=(filter_size - 1) // 2,\n",
    "                                   groups=groups,\n",
    "                                   act=None,\n",
    "                                   param_attr=ParamAttr(name=name + \"_weights\"),\n",
    "                                   bias_attr=False,\n",
    "                                   name=name + '.conv2d.output.1')\n",
    "        if name == \"conv1\":\n",
    "            bn_name = \"bn_\" + name\n",
    "        else:\n",
    "            bn_name = \"bn\" + name[3:]\n",
    "        return fluid.layers.batch_norm(input=conv,\n",
    "                                       act=act,\n",
    "                                       name=bn_name + '.output.1',\n",
    "                                       param_attr=ParamAttr(name=bn_name + '_scale'),\n",
    "                                       bias_attr=ParamAttr(bn_name + '_offset'),\n",
    "                                       moving_mean_name=bn_name + '_mean',\n",
    "                                       moving_variance_name=bn_name + '_variance', )\n",
    "\n",
    "    def shortcut(input, ch_out, stride, name):\n",
    "        ch_in = input.shape[1]\n",
    "        if ch_in != ch_out or stride != 1:\n",
    "            return conv_bn_layer(input, ch_out, 1, stride, name=name)\n",
    "        else:\n",
    "            return input\n",
    "            \n",
    "    def bottleneck_block(input, num_filters, stride, name):\n",
    "        conv0 = conv_bn_layer(input=input,\n",
    "                              num_filters=num_filters,\n",
    "                              filter_size=1,\n",
    "                              act='relu',\n",
    "                              name=name + \"_branch2a\")\n",
    "        conv1 = conv_bn_layer(input=conv0,\n",
    "                              num_filters=num_filters,\n",
    "                              filter_size=3,\n",
    "                              stride=stride,\n",
    "                              act='relu',\n",
    "                              name=name + \"_branch2b\")\n",
    "        conv2 = conv_bn_layer(input=conv1,\n",
    "                              num_filters=num_filters * 4,\n",
    "                              filter_size=1,\n",
    "                              act=None,\n",
    "                              name=name + \"_branch2c\")\n",
    "\n",
    "        short = shortcut(input, num_filters * 4, stride, name=name + \"_branch1\")\n",
    "\n",
    "        return fluid.layers.elementwise_add(x=short, y=conv2, act='relu', name=name + \".add.output.5\")\n",
    "\n",
    "    depth = [3, 4, 23, 3]\n",
    "    num_filters = [64, 128, 256, 512]\n",
    "\n",
    "    conv = conv_bn_layer(input=input, num_filters=64, filter_size=7, stride=2, act='relu', name=\"conv1\")\n",
    "    conv = fluid.layers.pool2d(input=conv, pool_size=3, pool_stride=2, pool_padding=1, pool_type='max')\n",
    "\n",
    "    for block in range(len(depth)):\n",
    "        for i in range(depth[block]):\n",
    "            if block == 2:\n",
    "                if i == 0:\n",
    "                    conv_name=\"res\"+str(block+2)+\"a\"\n",
    "                else:\n",
    "                    conv_name=\"res\"+str(block+2)+\"b\"+str(i)\n",
    "            else:\n",
    "                    conv_name=\"res\"+str(block+2)+chr(97+i)\n",
    "            conv = bottleneck_block(input=conv,\n",
    "                                    num_filters=num_filters[block],\n",
    "                                    stride=2 if i == 0 and block != 0 else 1,\n",
    "                                    name=conv_name)\n",
    "\n",
    "    pool = fluid.layers.pool2d(input=conv, pool_size=7, pool_type='avg', global_pooling=True)\n",
    "    return pool\n",
    "print('定义训练网络')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "配置预训练网络完成\n"
     ]
    }
   ],
   "source": [
    "##定义输入层\n",
    "image=fluid.layers.data(name='image',shape=reader.shape,dtype='float32')\n",
    "label=fluid.layers.data(name='label',shape=[1],dtype='int64')\n",
    "##停止梯度下降\n",
    "pool=resnet(image)\n",
    "pool.stop_gradient=True\n",
    "##创建主程序\n",
    "base_model_program=fluid.default_main_program().clone()\n",
    "model=fluid.layers.fc(input=pool,size=12,act='softmax')\n",
    "##定义损失函数和准确率函数\n",
    "cost=fluid.layers.cross_entropy(input=model,label=label)\n",
    "avg_cost=fluid.layers.mean(cost)\n",
    "acc=fluid.layers.accuracy(input=model,label=label)\n",
    "##定义优化方法\n",
    "optimizer=fluid.optimizer.AdamOptimizer(learning_rate=1e-4)\n",
    "opts=optimizer.minimize(avg_cost)\n",
    "##定义训练场所\n",
    "use_gpu=True # 使用高级版建议改成True\n",
    "place=fluid.CUDAPlace(0) if use_gpu else fluid.CPUPlace()\n",
    "exe=fluid.Executor(place)\n",
    "##进行参数初始化\n",
    "exe.run(fluid.default_startup_program())\n",
    "##定义数据维度\n",
    "feeder=fluid.DataFeeder(place=place,feed_list=[image,label])\n",
    "## 预训练参数路径\n",
    "model_pre_dir = \"work/pretrained/ResNet101_pretrained\"\n",
    "##判断模型文件是否存在\n",
    "def if_exit(var):\n",
    "    path=os.path.join(model_pre_dir,var.name)\n",
    "    exist=os.path.exists(path)\n",
    "    return exist\n",
    "##加载模型文件，且只加载存在模型的模型文件\n",
    "fluid.io.load_vars(executor=exe,dirname=model_pre_dir,predicate=if_exit,main_program=base_model_program)\n",
    "print('配置预训练网络完成')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "开始进行预训练\n",
      "\n",
      "Pass:0, Batch:0, Cost:0.93581, Accuracy:0.81250\n",
      "...............................................................................\n",
      "Pass:0, Batch:100, Cost:0.85141, Accuracy:0.87500\n",
      "............\n",
      "Pass:1, Batch:0, Cost:0.74658, Accuracy:0.87500\n",
      "...............................................\n",
      "Pass:1, Batch:50, Cost:1.03272, Accuracy:0.71875\n",
      ".................................................\n",
      "Pass:1, Batch:100, Cost:0.81921, Accuracy:0.71875\n",
      "............\n",
      "Pass:2, Batch:0, Cost:0.72923, Accuracy:0.90625\n",
      "...................................\n",
      "Pass:2, Batch:50, Cost:0.80558, Accuracy:0.78125\n",
      ".........................\n",
      "Pass:2, Batch:100, Cost:0.69165, Accuracy:0.87500\n",
      ".........\n",
      "Pass:3, Batch:0, Cost:0.74713, Accuracy:0.90625\n",
      ".................................................\n",
      "Pass:3, Batch:50, Cost:0.66762, Accuracy:0.78125\n",
      ".................................................\n",
      "Pass:3, Batch:100, Cost:0.76436, Accuracy:0.75000\n",
      "...........\n",
      "Pass:4, Batch:0, Cost:0.66394, Accuracy:0.81250\n",
      ".................................................\n",
      "Pass:4, Batch:50, Cost:0.72943, Accuracy:0.81250\n",
      ".................................................\n",
      "Pass:4, Batch:100, Cost:0.81246, Accuracy:0.78125\n",
      "\n",
      "Pass:5, Batch:0, Cost:0.87312, Accuracy:0.75000\n",
      ".................................................\n",
      "Pass:5, Batch:50, Cost:0.71800, Accuracy:0.81250\n",
      "..........................\n",
      "Pass:5, Batch:100, Cost:0.68601, Accuracy:0.84375\n",
      ".....\n",
      "Pass:6, Batch:0, Cost:0.78777, Accuracy:0.78125\n",
      "............................................................................\n",
      "Pass:6, Batch:100, Cost:0.37715, Accuracy:0.93750\n",
      ".........\n",
      "Pass:7, Batch:0, Cost:0.45125, Accuracy:0.93750\n",
      ".................................................\n",
      "Pass:7, Batch:50, Cost:0.68438, Accuracy:0.84375\n",
      "...........................................\n",
      "Pass:8, Batch:0, Cost:0.53149, Accuracy:0.90625\n",
      "...................................\n",
      "Pass:8, Batch:50, Cost:0.73657, Accuracy:0.78125\n",
      "..............................\n",
      "Pass:8, Batch:100, Cost:0.71849, Accuracy:0.81250\n",
      "............\n",
      "Pass:9, Batch:0, Cost:0.68666, Accuracy:0.78125\n",
      ".................................................\n",
      "Pass:9, Batch:50, Cost:0.58440, Accuracy:0.78125\n",
      ".........................\n",
      "Pass:9, Batch:100, Cost:0.76544, Accuracy:0.78125\n",
      ".........\n",
      "Pass:10, Batch:0, Cost:0.59603, Accuracy:0.78125\n",
      "..........................\n",
      "Pass:10, Batch:50, Cost:0.48276, Accuracy:0.87500\n",
      ".................................................\n",
      "Pass:10, Batch:100, Cost:0.52161, Accuracy:0.81250\n",
      ".................................................\n",
      "Pass:11, Batch:50, Cost:0.68682, Accuracy:0.81250\n",
      ".......................................\n",
      "Pass:12, Batch:0, Cost:0.42463, Accuracy:0.96875\n",
      ".................................................\n",
      "Pass:12, Batch:50, Cost:0.51353, Accuracy:0.75000\n",
      "...................................\n",
      "Pass:12, Batch:100, Cost:0.64171, Accuracy:0.78125\n",
      "...................................................\n",
      "Pass:13, Batch:50, Cost:0.43776, Accuracy:0.87500\n",
      "..............................\n",
      "Pass:13, Batch:100, Cost:0.58903, Accuracy:0.84375\n",
      "..........\n",
      "Pass:14, Batch:0, Cost:0.58587, Accuracy:0.87500\n",
      ".................................................\n",
      "Pass:14, Batch:50, Cost:0.48544, Accuracy:0.90625\n",
      ".................................................\n",
      "Pass:14, Batch:100, Cost:0.71429, Accuracy:0.78125\n",
      ".........\n",
      "Pass:15, Batch:0, Cost:0.58727, Accuracy:0.87500\n",
      ".................................................\n",
      "Pass:15, Batch:50, Cost:0.59403, Accuracy:0.81250\n",
      ".................................................\n",
      "Pass:15, Batch:100, Cost:0.45944, Accuracy:0.87500\n",
      ".........\n",
      "Pass:16, Batch:0, Cost:0.45694, Accuracy:0.84375\n",
      ".................................................\n",
      "Pass:16, Batch:50, Cost:0.32169, Accuracy:0.93750\n",
      "..............................\n",
      "Pass:16, Batch:100, Cost:0.72634, Accuracy:0.71875\n",
      ".........\n",
      "Pass:17, Batch:0, Cost:0.60555, Accuracy:0.84375\n",
      "...................................\n",
      "Pass:17, Batch:50, Cost:0.45701, Accuracy:0.87500\n",
      ".................................................\n",
      "Pass:17, Batch:100, Cost:0.41612, Accuracy:0.90625\n",
      ".........\n",
      "Pass:18, Batch:0, Cost:0.70837, Accuracy:0.84375\n",
      ".................................................\n",
      "Pass:18, Batch:50, Cost:0.75681, Accuracy:0.84375\n",
      ".................................................\n",
      "Pass:18, Batch:100, Cost:0.46418, Accuracy:0.90625\n",
      "..................................................\n",
      "Pass:19, Batch:50, Cost:0.47078, Accuracy:0.84375\n",
      "..............................\n",
      "Pass:19, Batch:100, Cost:0.49332, Accuracy:0.84375\n",
      ".........预训练完成\n"
     ]
    }
   ],
   "source": [
    "PRE_EPOCH_NUM = 20\n",
    "print('开始进行预训练')\n",
    "for pass_id in range(PRE_EPOCH_NUM):\n",
    "    for batch_id,data in enumerate(train_reader()):\n",
    "        train_cost,train_acc=exe.run(program = fluid.default_main_program(),feed=feeder.feed(data),fetch_list=[avg_cost,acc])\n",
    "        if batch_id%50==0:\n",
    "            print('\\nPass:%d, Batch:%d, Cost:%0.5f, Accuracy:%0.5f' %\n",
    "                  (pass_id, batch_id, train_cost[0], train_acc[0]))\n",
    "        else:\n",
    "            print('.',end='')\n",
    "print('预训练完成')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "save_pretrain_model_path='/home/aistudio/work/models/pre/'\n",
    "##删除旧的模型文件\n",
    "shutil.rmtree(save_pretrain_model_path,ignore_errors=True)\n",
    "##创建保存模型文件记录\n",
    "os.makedirs(save_pretrain_model_path)\n",
    "##保存参数模型\n",
    "fluid.io.save_params(executor=exe,dirname=save_pretrain_model_path)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "#### 开始正式训练"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# 重启开始正式训练\n",
    "import paddle.fluid as fluid\n",
    "import paddle\n",
    "from paddle.fluid.param_attr import ParamAttr\n",
    "import numpy as np\n",
    "from PIL import Image\n",
    "import os\n",
    "import random\n",
    "from multiprocessing import cpu_count\n",
    "import matplotlib.pyplot as plt\n",
    "import shutil\n",
    "import pandas as pd\n",
    "import reader"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "train_path = r'train_data.txt'\r\n",
    "BATCH_SIZE = 32 # 批处理数据的大小\r\n",
    "train_reader = paddle.batch(\r\n",
    "    reader=paddle.reader.shuffle(reader=reader.custom_image_reader(train_path, mode='train'),buf_size=1280000), \r\n",
    "     batch_size=BATCH_SIZE)\r\n",
    "test_reader = paddle.batch(reader.custom_image_reader(train_path, mode='test'),\r\n",
    "                        batch_size=BATCH_SIZE)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "##定义resnet，加上fc\n",
    "def resnet(input,class_dim):\n",
    "    def conv_bn_layer(input, num_filters, filter_size, stride=1, groups=1, act=None, name=None):\n",
    "        conv = fluid.layers.conv2d(input=input,\n",
    "                                   num_filters=num_filters,\n",
    "                                   filter_size=filter_size,\n",
    "                                   stride=stride,\n",
    "                                   padding=(filter_size - 1) // 2,\n",
    "                                   groups=groups,\n",
    "                                   act=None,\n",
    "                                   param_attr=ParamAttr(name=name + \"_weights\"),\n",
    "                                   bias_attr=False,\n",
    "                                   name=name + '.conv2d.output.1')\n",
    "        if name == \"conv1\":\n",
    "            bn_name = \"bn_\" + name\n",
    "        else:\n",
    "            bn_name = \"bn\" + name[3:]\n",
    "        return fluid.layers.batch_norm(input=conv,\n",
    "                                       act=act,\n",
    "                                       name=bn_name + '.output.1',\n",
    "                                       param_attr=ParamAttr(name=bn_name + '_scale'),\n",
    "                                       bias_attr=ParamAttr(bn_name + '_offset'),\n",
    "                                       moving_mean_name=bn_name + '_mean',\n",
    "                                       moving_variance_name=bn_name + '_variance', )\n",
    "\n",
    "    def shortcut(input, ch_out, stride, name):\n",
    "        ch_in = input.shape[1]\n",
    "        if ch_in != ch_out or stride != 1:\n",
    "            return conv_bn_layer(input, ch_out, 1, stride, name=name)\n",
    "        else:\n",
    "            return input\n",
    "            \n",
    "    def bottleneck_block(input, num_filters, stride, name):\n",
    "        conv0 = conv_bn_layer(input=input,\n",
    "                              num_filters=num_filters,\n",
    "                              filter_size=1,\n",
    "                              act='relu',\n",
    "                              name=name + \"_branch2a\")\n",
    "        conv1 = conv_bn_layer(input=conv0,\n",
    "                              num_filters=num_filters,\n",
    "                              filter_size=3,\n",
    "                              stride=stride,\n",
    "                              act='relu',\n",
    "                              name=name + \"_branch2b\")\n",
    "        conv2 = conv_bn_layer(input=conv1,\n",
    "                              num_filters=num_filters * 4,\n",
    "                              filter_size=1,\n",
    "                              act=None,\n",
    "                              name=name + \"_branch2c\")\n",
    "\n",
    "        short = shortcut(input, num_filters * 4, stride, name=name + \"_branch1\")\n",
    "\n",
    "        return fluid.layers.elementwise_add(x=short, y=conv2, act='relu', name=name + \".add.output.5\")\n",
    "\n",
    "    depth = [3, 4, 23, 3]\n",
    "    num_filters = [64, 128, 256, 512]\n",
    "\n",
    "    conv = conv_bn_layer(input=input, num_filters=64, filter_size=7, stride=2, act='relu', name=\"conv1\")\n",
    "    conv = fluid.layers.pool2d(input=conv, pool_size=3, pool_stride=2, pool_padding=1, pool_type='max')\n",
    "\n",
    "    for block in range(len(depth)):\n",
    "        for i in range(depth[block]):\n",
    "            if block == 2:\n",
    "                if i == 0:\n",
    "                    conv_name=\"res\"+str(block+2)+\"a\"\n",
    "                else:\n",
    "                    conv_name=\"res\"+str(block+2)+\"b\"+str(i)\n",
    "            else:\n",
    "                    conv_name=\"res\"+str(block+2)+chr(97+i)\n",
    "            conv = bottleneck_block(input=conv,\n",
    "                                    num_filters=num_filters[block],\n",
    "                                    stride=2 if i == 0 and block != 0 else 1,\n",
    "                                    name=conv_name)\n",
    "\n",
    "    pool = fluid.layers.pool2d(input=conv, pool_size=7, pool_type='avg', global_pooling=True)\n",
    "    output=fluid.layers.fc(input=pool,size=class_dim,act='softmax')\n",
    "    return output"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "配置网络完成\n"
     ]
    }
   ],
   "source": [
    "##定义输入层\n",
    "image=fluid.layers.data(name='image',shape=reader.shape,dtype='float32')\n",
    "label = fluid.layers.data(name='label', shape=[1], dtype='int64')\n",
    "##获取分类器\n",
    "model = resnet(image,12)\n",
    "# 获取损失函数和准确率,选择交叉熵损失函数\n",
    "cost = fluid.layers.cross_entropy(input=model, label=label)\n",
    "avg_cost = fluid.layers.mean(cost)\n",
    "acc = fluid.layers.accuracy(input=model, label=label,k=1)\n",
    "##获取训练和测试程序\n",
    "test_program = fluid.default_main_program().clone(for_test=True)\n",
    "##定义优化方法\n",
    "optimizer=fluid.optimizer.AdamOptimizer(learning_rate=1e-5)\n",
    "opts=optimizer.minimize(avg_cost)\n",
    "##定义一个使用GPU的执行器\n",
    "use_gpu=True # 高级版建议改成True\n",
    "place=fluid.CUDAPlace(0) if use_gpu else fluid.CPUPlace()\n",
    "exe=fluid.Executor(place)\n",
    "##进行参数初始化\n",
    "exe.run(fluid.default_startup_program())\n",
    "##经过step-1处理后的的预训练模型\n",
    "pretrained_model_path = '/home/aistudio/work/models/pre/'\n",
    "##加载经过处理的模型\n",
    "fluid.io.load_params(executor=exe, dirname=pretrained_model_path)\n",
    "##定义数据维度\n",
    "feeder=fluid.DataFeeder(place=place,feed_list=[image,label])\n",
    "print('配置网络完成')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "开始训练\n",
      "Pass:0, Batch:0, Cost:0.58340, Accuracy:0.81250\n",
      "Pass:0, Batch:20, Cost:0.31626, Accuracy:0.90625\n",
      "Pass:0, Batch:30, Cost:0.43537, Accuracy:0.84375\n",
      "Pass:0, Batch:40, Cost:0.21202, Accuracy:0.96875\n",
      "Pass:0, Batch:50, Cost:0.31577, Accuracy:0.93750\n",
      "Pass:0, Batch:60, Cost:0.54503, Accuracy:0.81250\n",
      "Pass:0, Batch:70, Cost:0.18198, Accuracy:0.93750\n",
      "Pass:0, Batch:90, Cost:0.28081, Accuracy:0.93750\n",
      "Pass:0, Batch:100, Cost:0.49754, Accuracy:0.84375\n",
      "Test:0, Cost:0.17646, Accuracy:0.95811\n",
      "Pass:1, Batch:0, Cost:0.35621, Accuracy:0.84375\n",
      "Pass:1, Batch:10, Cost:0.23368, Accuracy:0.93750\n",
      "Pass:1, Batch:20, Cost:0.44836, Accuracy:0.81250\n",
      "Pass:1, Batch:30, Cost:0.34583, Accuracy:0.81250\n",
      "Pass:1, Batch:50, Cost:0.16972, Accuracy:0.96875\n",
      "Pass:1, Batch:60, Cost:0.27532, Accuracy:0.90625\n",
      "Pass:1, Batch:70, Cost:0.28763, Accuracy:0.90625\n",
      "Pass:1, Batch:80, Cost:0.28017, Accuracy:0.90625\n",
      "Pass:1, Batch:90, Cost:0.12311, Accuracy:1.00000\n",
      "Pass:1, Batch:100, Cost:0.08726, Accuracy:1.00000\n",
      "Pass:1, Batch:110, Cost:0.19809, Accuracy:0.96875\n",
      "Test:1, Cost:0.11786, Accuracy:0.97079\n",
      "Pass:2, Batch:0, Cost:0.29770, Accuracy:0.84375\n",
      "Pass:2, Batch:10, Cost:0.14329, Accuracy:1.00000\n",
      "Pass:2, Batch:20, Cost:0.10206, Accuracy:1.00000\n",
      "Pass:2, Batch:30, Cost:0.31645, Accuracy:0.87500\n",
      "Pass:2, Batch:40, Cost:0.51111, Accuracy:0.84375\n",
      "Pass:2, Batch:50, Cost:0.22270, Accuracy:0.90625\n",
      "Pass:2, Batch:60, Cost:0.22722, Accuracy:0.93750\n",
      "Pass:2, Batch:70, Cost:0.42237, Accuracy:0.87500\n",
      "Pass:2, Batch:90, Cost:0.18528, Accuracy:0.93750\n",
      "Pass:2, Batch:100, Cost:0.20524, Accuracy:0.93750\n",
      "Pass:2, Batch:110, Cost:0.18449, Accuracy:0.92308\n",
      "Test:2, Cost:0.08516, Accuracy:0.97956\n",
      "Pass:3, Batch:0, Cost:0.15179, Accuracy:0.96875\n",
      "Pass:3, Batch:10, Cost:0.41632, Accuracy:0.81250\n",
      "Pass:3, Batch:20, Cost:0.29830, Accuracy:0.84375\n",
      "Pass:3, Batch:30, Cost:0.37138, Accuracy:0.90625\n",
      "Pass:3, Batch:50, Cost:0.14396, Accuracy:0.96875\n",
      "Pass:3, Batch:60, Cost:0.10840, Accuracy:0.96875\n",
      "Pass:3, Batch:70, Cost:0.14484, Accuracy:0.90625\n",
      "Pass:3, Batch:80, Cost:0.18967, Accuracy:0.93750\n",
      "Pass:3, Batch:90, Cost:0.09513, Accuracy:0.96875\n",
      "Pass:3, Batch:100, Cost:0.24952, Accuracy:0.93750\n",
      "Test:3, Cost:0.12769, Accuracy:0.97394\n",
      "Pass:4, Batch:0, Cost:0.22793, Accuracy:0.93750\n",
      "Pass:4, Batch:10, Cost:0.17703, Accuracy:0.90625\n",
      "Pass:4, Batch:20, Cost:0.16816, Accuracy:0.96875\n",
      "Pass:4, Batch:30, Cost:0.18268, Accuracy:0.96875\n",
      "Pass:4, Batch:50, Cost:0.33097, Accuracy:0.90625\n",
      "Pass:4, Batch:60, Cost:0.17601, Accuracy:0.90625\n",
      "Pass:4, Batch:70, Cost:0.31491, Accuracy:0.90625\n",
      "Pass:4, Batch:80, Cost:0.23983, Accuracy:0.93750\n",
      "Pass:4, Batch:90, Cost:0.18396, Accuracy:0.93750\n",
      "Pass:4, Batch:100, Cost:0.11638, Accuracy:0.93750\n",
      "Test:4, Cost:0.05578, Accuracy:0.98876\n",
      "Pass:5, Batch:0, Cost:0.26420, Accuracy:0.90625\n",
      "Pass:5, Batch:10, Cost:0.14139, Accuracy:0.93750\n",
      "Pass:5, Batch:20, Cost:0.10014, Accuracy:0.96875\n",
      "Pass:5, Batch:30, Cost:0.23140, Accuracy:0.90625\n",
      "Pass:5, Batch:40, Cost:0.31611, Accuracy:0.96875\n",
      "Pass:5, Batch:50, Cost:0.05358, Accuracy:1.00000\n",
      "Pass:5, Batch:60, Cost:0.08463, Accuracy:0.96875\n",
      "Pass:5, Batch:70, Cost:0.13216, Accuracy:1.00000\n",
      "Pass:5, Batch:80, Cost:0.36585, Accuracy:0.90625\n",
      "Pass:5, Batch:90, Cost:0.26217, Accuracy:0.93750\n",
      "Pass:5, Batch:100, Cost:0.30847, Accuracy:0.90625\n",
      "Pass:5, Batch:110, Cost:0.25649, Accuracy:0.87097\n",
      "Test:5, Cost:0.06461, Accuracy:0.98442\n",
      "Pass:6, Batch:0, Cost:0.26669, Accuracy:0.87500\n",
      "Pass:6, Batch:10, Cost:0.12697, Accuracy:0.96875\n",
      "Pass:6, Batch:20, Cost:0.19841, Accuracy:0.90625\n",
      "Pass:6, Batch:40, Cost:0.08504, Accuracy:0.96875\n",
      "Pass:6, Batch:50, Cost:0.25158, Accuracy:0.87500\n",
      "Pass:6, Batch:60, Cost:0.19877, Accuracy:0.96875\n",
      "Pass:6, Batch:70, Cost:0.25654, Accuracy:0.93750\n",
      "Pass:6, Batch:80, Cost:0.16659, Accuracy:0.93750\n",
      "Pass:6, Batch:90, Cost:0.37278, Accuracy:0.87500\n",
      "Pass:6, Batch:100, Cost:0.21040, Accuracy:0.93750\n",
      "Test:6, Cost:0.03175, Accuracy:0.99217\n",
      "Pass:7, Batch:0, Cost:0.10504, Accuracy:1.00000\n",
      "Pass:7, Batch:20, Cost:0.06910, Accuracy:1.00000\n",
      "Pass:7, Batch:30, Cost:0.30862, Accuracy:0.90625\n",
      "Pass:7, Batch:40, Cost:0.10031, Accuracy:0.96875\n",
      "Pass:7, Batch:50, Cost:0.28948, Accuracy:0.90625\n",
      "Pass:7, Batch:60, Cost:0.13394, Accuracy:0.93750\n",
      "Pass:7, Batch:70, Cost:0.03889, Accuracy:1.00000\n",
      "Pass:7, Batch:80, Cost:0.07521, Accuracy:0.96875\n",
      "Pass:7, Batch:90, Cost:0.19833, Accuracy:0.96875\n",
      "Pass:7, Batch:100, Cost:0.22087, Accuracy:0.93750\n",
      "Test:7, Cost:0.03251, Accuracy:0.99225\n",
      "Pass:8, Batch:0, Cost:0.08528, Accuracy:1.00000\n",
      "Pass:8, Batch:10, Cost:0.12945, Accuracy:0.93750\n",
      "Pass:8, Batch:20, Cost:0.11564, Accuracy:0.93750\n",
      "Pass:8, Batch:30, Cost:0.42626, Accuracy:0.84375\n",
      "Pass:8, Batch:40, Cost:0.29853, Accuracy:0.90625\n",
      "Pass:8, Batch:60, Cost:0.20458, Accuracy:0.90625\n",
      "Pass:8, Batch:70, Cost:0.04593, Accuracy:1.00000\n",
      "Pass:8, Batch:80, Cost:0.18247, Accuracy:0.87500\n",
      "Pass:8, Batch:100, Cost:0.18493, Accuracy:0.90625\n",
      "Test:8, Cost:0.02713, Accuracy:0.99404\n",
      "Pass:9, Batch:10, Cost:0.06452, Accuracy:0.96875\n",
      "Pass:9, Batch:30, Cost:0.15244, Accuracy:0.93750\n",
      "Pass:9, Batch:40, Cost:0.10823, Accuracy:0.96875\n",
      "Pass:9, Batch:50, Cost:0.19796, Accuracy:0.96875\n",
      "Pass:9, Batch:70, Cost:0.03908, Accuracy:1.00000\n",
      "Pass:9, Batch:80, Cost:0.08553, Accuracy:1.00000\n",
      "Pass:9, Batch:90, Cost:0.17809, Accuracy:0.90625\n",
      "Pass:10, Batch:0, Cost:0.32553, Accuracy:0.84375\n",
      "Pass:10, Batch:10, Cost:0.17311, Accuracy:0.96875\n",
      "Pass:10, Batch:20, Cost:0.14272, Accuracy:0.93750\n",
      "Pass:10, Batch:30, Cost:0.05980, Accuracy:0.96875\n",
      "Pass:10, Batch:40, Cost:0.37914, Accuracy:0.90625\n",
      "Pass:10, Batch:50, Cost:0.11434, Accuracy:0.96875\n",
      "Pass:10, Batch:70, Cost:0.18668, Accuracy:0.90625\n",
      "Pass:10, Batch:80, Cost:0.24966, Accuracy:0.93750\n",
      "Pass:10, Batch:90, Cost:0.17783, Accuracy:0.93750\n",
      "Pass:10, Batch:100, Cost:0.06354, Accuracy:1.00000\n",
      "Pass:10, Batch:110, Cost:0.42873, Accuracy:0.87500\n",
      "Test:10, Cost:0.02033, Accuracy:0.99719\n",
      "Pass:11, Batch:0, Cost:0.27736, Accuracy:0.90625\n",
      "Pass:11, Batch:10, Cost:0.11046, Accuracy:0.96875\n",
      "Pass:11, Batch:20, Cost:0.04813, Accuracy:1.00000\n",
      "Pass:11, Batch:40, Cost:0.14833, Accuracy:0.96875\n",
      "Pass:11, Batch:50, Cost:0.02907, Accuracy:1.00000\n",
      "Pass:11, Batch:60, Cost:0.04913, Accuracy:1.00000\n",
      "Pass:11, Batch:70, Cost:0.06544, Accuracy:1.00000\n",
      "Pass:11, Batch:80, Cost:0.11532, Accuracy:0.96875\n",
      "Pass:11, Batch:90, Cost:0.08305, Accuracy:1.00000\n",
      "Pass:11, Batch:100, Cost:0.09628, Accuracy:0.93750\n",
      "Test:11, Cost:0.02178, Accuracy:0.99489\n",
      "Pass:12, Batch:0, Cost:0.14461, Accuracy:0.93750\n",
      "Pass:12, Batch:10, Cost:0.24982, Accuracy:0.87500\n",
      "Pass:12, Batch:30, Cost:0.04159, Accuracy:1.00000\n",
      "Pass:12, Batch:40, Cost:0.08595, Accuracy:1.00000\n",
      "Pass:12, Batch:50, Cost:0.06067, Accuracy:0.96875\n",
      "Pass:12, Batch:60, Cost:0.03285, Accuracy:1.00000\n",
      "Pass:12, Batch:70, Cost:0.16538, Accuracy:0.96875\n",
      "Pass:12, Batch:80, Cost:0.26010, Accuracy:0.90625\n",
      "Pass:12, Batch:90, Cost:0.17998, Accuracy:0.93750\n",
      "Pass:12, Batch:100, Cost:0.05756, Accuracy:1.00000\n",
      "Test:12, Cost:0.01512, Accuracy:0.99753\n",
      "Pass:13, Batch:0, Cost:0.05593, Accuracy:1.00000\n",
      "Pass:13, Batch:10, Cost:0.05597, Accuracy:0.96875\n",
      "Pass:13, Batch:20, Cost:0.23061, Accuracy:0.93750\n",
      "Pass:13, Batch:30, Cost:0.07854, Accuracy:1.00000\n",
      "Pass:13, Batch:40, Cost:0.05705, Accuracy:1.00000\n",
      "Pass:13, Batch:50, Cost:0.10588, Accuracy:0.96875\n",
      "Pass:13, Batch:60, Cost:0.08743, Accuracy:0.96875\n",
      "Pass:13, Batch:70, Cost:0.00855, Accuracy:1.00000\n",
      "Pass:13, Batch:80, Cost:0.10988, Accuracy:0.93750\n",
      "Pass:13, Batch:90, Cost:0.09688, Accuracy:1.00000\n",
      "Pass:13, Batch:100, Cost:0.02636, Accuracy:1.00000\n",
      "Test:13, Cost:0.01895, Accuracy:0.99634\n",
      "Pass:14, Batch:0, Cost:0.12606, Accuracy:0.93750\n",
      "Pass:14, Batch:10, Cost:0.02420, Accuracy:1.00000\n",
      "Pass:14, Batch:20, Cost:0.18740, Accuracy:0.93750\n",
      "Pass:14, Batch:30, Cost:0.21558, Accuracy:0.96875\n",
      "Pass:14, Batch:40, Cost:0.09463, Accuracy:0.96875\n",
      "Pass:14, Batch:50, Cost:0.03737, Accuracy:1.00000\n",
      "Pass:14, Batch:60, Cost:0.45999, Accuracy:0.87500\n",
      "Pass:14, Batch:70, Cost:0.02538, Accuracy:1.00000\n",
      "Pass:14, Batch:80, Cost:0.11525, Accuracy:0.96875\n",
      "Pass:14, Batch:90, Cost:0.14858, Accuracy:0.96875\n",
      "Pass:14, Batch:100, Cost:0.06693, Accuracy:0.96875\n",
      "Pass:14, Batch:110, Cost:0.97444, Accuracy:0.57143\n",
      "Test:14, Cost:0.02086, Accuracy:0.99634\n",
      "Pass:15, Batch:0, Cost:0.01600, Accuracy:1.00000\n",
      "Pass:15, Batch:10, Cost:0.03678, Accuracy:1.00000\n",
      "Pass:15, Batch:20, Cost:0.28780, Accuracy:0.87500\n",
      "Pass:15, Batch:30, Cost:0.19420, Accuracy:0.93750\n",
      "Pass:15, Batch:50, Cost:0.11352, Accuracy:0.93750\n",
      "Pass:15, Batch:60, Cost:0.29168, Accuracy:0.87500\n",
      "Pass:15, Batch:80, Cost:0.13052, Accuracy:0.96875\n",
      "Pass:15, Batch:90, Cost:0.13446, Accuracy:0.96875\n",
      "Pass:15, Batch:100, Cost:0.10132, Accuracy:1.00000\n",
      "Test:15, Cost:0.02000, Accuracy:0.99574\n",
      "Pass:16, Batch:0, Cost:0.06187, Accuracy:0.96875\n",
      "Pass:16, Batch:10, Cost:0.15031, Accuracy:0.96875\n",
      "Pass:16, Batch:20, Cost:0.03156, Accuracy:1.00000\n",
      "Pass:16, Batch:40, Cost:0.07716, Accuracy:0.96875\n",
      "Pass:16, Batch:50, Cost:0.16928, Accuracy:0.93750\n",
      "Pass:16, Batch:60, Cost:0.17409, Accuracy:0.96875\n",
      "Pass:16, Batch:70, Cost:0.03399, Accuracy:1.00000\n",
      "Pass:16, Batch:80, Cost:0.07334, Accuracy:1.00000\n",
      "Pass:16, Batch:90, Cost:0.10016, Accuracy:0.96875\n",
      "Test:16, Cost:0.01324, Accuracy:0.99659\n",
      "Pass:17, Batch:0, Cost:0.07597, Accuracy:0.96875\n",
      "Pass:17, Batch:10, Cost:0.23877, Accuracy:0.93750\n",
      "Pass:17, Batch:20, Cost:0.02761, Accuracy:1.00000\n",
      "Pass:17, Batch:30, Cost:0.21510, Accuracy:0.93750\n",
      "Pass:17, Batch:40, Cost:0.06227, Accuracy:0.96875\n",
      "Pass:17, Batch:50, Cost:0.02709, Accuracy:1.00000\n",
      "Pass:17, Batch:60, Cost:0.14881, Accuracy:0.93750\n",
      "Pass:17, Batch:70, Cost:0.07299, Accuracy:0.96875\n",
      "Pass:17, Batch:90, Cost:0.28208, Accuracy:0.93750\n",
      "Pass:17, Batch:100, Cost:0.00882, Accuracy:1.00000\n",
      "Pass:17, Batch:110, Cost:0.22692, Accuracy:0.88889\n",
      "Test:17, Cost:0.01171, Accuracy:0.99796\n",
      "Pass:18, Batch:0, Cost:0.10570, Accuracy:0.93750\n",
      "Pass:18, Batch:20, Cost:0.04997, Accuracy:0.96875\n",
      "Pass:18, Batch:30, Cost:0.08418, Accuracy:0.96875\n",
      "Pass:18, Batch:40, Cost:0.11225, Accuracy:0.93750\n",
      "Pass:18, Batch:50, Cost:0.13629, Accuracy:0.93750\n",
      "Pass:18, Batch:60, Cost:0.02663, Accuracy:1.00000\n",
      "Pass:18, Batch:70, Cost:0.10932, Accuracy:0.96875\n",
      "Pass:18, Batch:80, Cost:0.08722, Accuracy:0.96875\n",
      "Pass:18, Batch:90, Cost:0.04102, Accuracy:0.96875\n",
      "Pass:18, Batch:100, Cost:0.12229, Accuracy:0.93750\n",
      "Pass:18, Batch:110, Cost:0.05439, Accuracy:1.00000\n",
      "Test:18, Cost:0.01300, Accuracy:0.99506\n",
      "Pass:19, Batch:0, Cost:0.06179, Accuracy:1.00000\n",
      "Pass:19, Batch:10, Cost:0.11123, Accuracy:0.93750\n",
      "Pass:19, Batch:20, Cost:0.18986, Accuracy:0.90625\n",
      "Pass:19, Batch:30, Cost:0.09971, Accuracy:0.96875\n",
      "Pass:19, Batch:40, Cost:0.03736, Accuracy:0.96875\n",
      "Pass:19, Batch:50, Cost:0.22808, Accuracy:0.90625\n",
      "Pass:19, Batch:70, Cost:0.06128, Accuracy:1.00000\n",
      "Pass:19, Batch:80, Cost:0.11227, Accuracy:0.93750\n",
      "Pass:19, Batch:90, Cost:0.06979, Accuracy:0.96875\n",
      "Pass:19, Batch:100, Cost:0.15647, Accuracy:0.93750\n",
      "Test:19, Cost:0.03902, Accuracy:0.99149\n",
      "训练完成\n"
     ]
    }
   ],
   "source": [
    "EPOCH_NUM = 20\n",
    "print('开始训练')\n",
    "for pass_id in range(EPOCH_NUM):\n",
    "    ##训练\n",
    "    for batch_id,data in enumerate(train_reader()):\n",
    "        train_cost,train_acc=exe.run(program=fluid.default_main_program(),feed=feeder.feed(data),fetch_list=[avg_cost,acc])\n",
    "        if batch_id%10==0:\n",
    "            print('Pass:%d, Batch:%d, Cost:%0.5f, Accuracy:%0.5f' %\n",
    "                  (pass_id, batch_id, train_cost[0], train_acc[0]))\n",
    "    ##测试\n",
    "    test_accs=[]\n",
    "    test_costs=[]\n",
    "    for batch_id,data in enumerate(test_reader()):\n",
    "        test_cost,test_acc=exe.run(program=test_program,feed=feeder.feed(data), fetch_list=[avg_cost,acc])\n",
    "        test_accs.append(test_acc[0])\n",
    "        test_costs.append(test_cost[0])\n",
    "    test_cost = (sum(test_costs) / len(test_costs))\n",
    "    test_acc = (sum(test_accs) / len(test_accs))\n",
    "    print('Test:%d, Cost:%0.5f, Accuracy:%0.5f' % (pass_id, test_cost, test_acc))\n",
    "print('训练完成')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['fc_0.tmp_2']"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "##保存预测模型\n",
    "save_path = 'models/normal/'\n",
    "##删除旧的模型文件\n",
    "shutil.rmtree(save_path, ignore_errors=True)\n",
    "##创建保持模型文件目录\n",
    "os.makedirs(save_path)\n",
    "##保存预测模型\n",
    "fluid.io.save_inference_model(save_path, feeded_var_names=[image.name], target_vars=[model], executor=exe)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# 解压预测数据集 首次运行需解压\r\n",
    "# !unzip -q data/data10954/cat_12_test.zip"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# 导入预处理的包\r\n",
    "import os\r\n",
    "import paddle\r\n",
    "import paddle.fluid as fluid\r\n",
    "import numpy as np\r\n",
    "from PIL import Image\r\n",
    "import sys\r\n",
    "import reader"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# 模型预测\r\n",
    "use_gpu=True\r\n",
    "place=fluid.CUDAPlace(0) if use_gpu else fluid.CPUPlace()\r\n",
    "exe=fluid.Executor(place)\r\n",
    "model_save_dir = 'models/normal/'\r\n",
    "infer_exe = fluid.Executor(place)\r\n",
    "inference_scope = fluid.core.Scope() \r\n",
    "result_file = r'result.csv'\r\n",
    "test_data_path = r'cat_12_test'\r\n",
    "test_data_imgs = os.listdir(test_data_path)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "def load_image(file):\r\n",
    "    #打开图片\r\n",
    "    img = Image.open(file)\r\n",
    "    #将图片调整为跟训练数据一样的大小，设定ANTIALIAS，即抗锯齿.resize是缩放\r\n",
    "    img = img.resize((224, 224), Image.ANTIALIAS)\r\n",
    "    #建立图片矩阵 类型为float32\r\n",
    "    if img.mode != 'RGB':\r\n",
    "        img = img.convert('RGB')# 需要转化为三通道，有些图片为单通道\r\n",
    "    im = np.array(img).astype(np.float32) \r\n",
    "    #矩阵转置 \r\n",
    "    im = im.transpose((2, 0, 1)d)                               \r\n",
    "    #将像素值从【0-255】转换为【0-1】\r\n",
    "    im = im / 255.0\r\n",
    "    im = np.expand_dims(im, axis=0)\r\n",
    "    # 保持和之前输入image维度一致\r\n",
    "    return im"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "预测完成\n"
     ]
    }
   ],
   "source": [
    "with fluid.scope_guard(inference_scope):\r\n",
    "    #从指定目录中加载 推理model(inference model)\r\n",
    "    [inference_program, # 预测用的program\r\n",
    "     feed_target_names, # 是一个str列表，它包含需要在推理 Program 中提供数据的变量的名称。 \r\n",
    "     fetch_targets] = fluid.io.load_inference_model(model_save_dir,#fetch_targets：是一个 Variable 列表，从中我们可以得到推断结果。\r\n",
    "                                                    infer_exe)     #infer_exe: 运行 inference model的 executor\r\n",
    "    with open(result_file,'w') as f_result:\r\n",
    "        for i in range(len(test_data_imgs)):\r\n",
    "            infer_path = os.path.join(test_data_path, test_data_imgs[i])\r\n",
    "            img = load_image(infer_path)\r\n",
    "            results = infer_exe.run(inference_program,                 #运行预测程序\r\n",
    "                                    feed={feed_target_names[0]: img},  #喂入要预测的img\r\n",
    "                                    fetch_list=fetch_targets)          #得到推测结果\r\n",
    "            # 输出样例：gN2xK8HUbjFWl1kGyCvMJehiBPwzSdOu.jpg,9\r\n",
    "            f_result.write(test_data_imgs[i]+','+ str(np.argmax(results[0]))+ '\\n')\r\n",
    "    print('预测完成')"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "PaddlePaddle 1.7.0 (Python 3.5)",
   "language": "python",
   "name": "py35-paddle1.2.0"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
